//******************************************************************/
//版本说明:
//V0.5		2010-10-27	22:35	yshao
//				双口sram改为使用swsr16_8_ddp，添加原来没有的输出时钟端口
//******************************************************************/
module v8_state_ctrl_02(
		input   wire            resetb,
        	input   wire            sclk,

		//和通讯模块接口
		input	wire		fpga_rec_flag,
		input	wire	[15:0]	ext_addr,
		input	wire	[15:0]	set_addr,
		input	wire		set_d_ok,
		input	wire	[7:0]	set_data,
		
		//千兆PHY接口
		input	wire		rec_flag,
		input	wire		rec_error,
	        
		//状态寄存器
		output 	reg	[7:0]	state_data,
		
		//其他状态数据
		input	wire	[7:0]	rd_data,
		
		//其他状态数据
		input	wire	[15:0]	debug_data,
		
		//设备模式
		input	wire		sub_mode,
		
		//输出给led灯和输出控制模块
		output 	wire	[7:0]	tout
		);

//******************************************************************/
//			   信号定义
//******************************************************************/		
//程序版本信息
parameter	main_function	=  "S";		//ASCII "S"  
parameter	sub_function	=  "L";		//ASCII "L"  
parameter	main_solution	=  9;		//"9"        
parameter	sub_solution	=  9;		//"09"       
parameter	application_type=  "G";		//ASCII "G"  
parameter	main_version	=  8'd3;	//"03"       
parameter	sub_version	=  8'd8;	//"X01"  
parameter	mini_version	=  8'd1;	//" "  

reg		rec_flag_t;
reg	[2:0]	counter,counter_t,counter_tt;
reg		add_flag,add_flag_t,add_flag_tt;
reg		clr_flag,clr_flag_t;
reg		load_flag,load_flag_t;
reg	[8:0]	adder;
reg		cin;
reg		buf_wea;
reg	[3:0]	buf_waddr;
reg	[7:0]	buf_wdata;
reg	[3:0]	buf_raddr;
wire	[7:0]	buf_rdata;
reg     [7:0]   state_version;

reg	[15:0]	crc_error_sum_1,crc_error_sum_2;
reg	[31:0]	pkt_sum_1,pkt_sum_2;
reg		full_crc;
reg		full_pkt;

//*************************************************************************
//				调试相关
//*************************************************************************
reg		debug_flag;

//调试标志
always@(posedge sclk)
	if ((set_addr == 16'h0400) && (set_d_ok == 1)) begin
		if (set_data == 8'h3C)
			debug_flag <= 1'b1;
		else 
			debug_flag <= 1'b0;
		end

//*************************************************************************
//				通讯包错误统计
//*************************************************************************

always@(posedge sclk, negedge resetb)
	if(!resetb)
		rec_flag_t<=1'b0;
	else
		rec_flag_t<=rec_flag;

always@(posedge sclk)
	if(set_addr==16'h0000 && set_d_ok == 1 && set_data==8'h00 && fpga_rec_flag=='d1)
		clr_flag<=1'b1;
	else 
		clr_flag<=1'b0;

always@(posedge sclk)
	if(set_addr==16'h0000 && set_d_ok == 1 && set_data==8'h02)
		load_flag <= 1'b1;
	else
		load_flag <= 1'b0;

always @(posedge sclk)
	if(clr_flag)
		pkt_sum_1<='d0;
	else if(rec_flag_t=='d0 && rec_flag=='d1 && full_pkt=='d0)//pkt_sum_1<32'HFFFF_FFFF)
		pkt_sum_1<=pkt_sum_1+'d1;

always @(posedge sclk)
	if(clr_flag)
		crc_error_sum_1<='d0;
	else if(rec_flag_t=='d0 && rec_flag=='d1 && rec_error=='d1 && full_crc=='d0)//crc_error_sum_1<16'HFFFF)
		crc_error_sum_1<=crc_error_sum_1+'d1;

always @(posedge sclk)
	if((&crc_error_sum_1[15:1])=='d1)
		full_crc<='d1;
	else 
		full_crc<='d0;

always @(posedge sclk)
	if((&pkt_sum_1[31:1])=='d1)
		full_pkt<='d1;
	else 
		full_pkt<='d0;		

always @(posedge sclk)
	if(clr_flag)
		pkt_sum_2<='d0;
	else if(load_flag)
		pkt_sum_2<=pkt_sum_1;

always @(posedge sclk)
	if (debug_flag == 1)
		crc_error_sum_2 <= debug_data;
	else if (clr_flag == 1)
		crc_error_sum_2 <= 16'h0;
	else if(load_flag)
		crc_error_sum_2 <= crc_error_sum_1;

reg		state_active;
		
always @(posedge sclk)
	if (ext_addr == 16'h0 && set_addr[15:8] == 8'h0)
		state_active <= 1;
	else
		state_active <= 0;
		
always @(posedge sclk)
	if (state_active == 0)
		state_data <= 0;
	else
		case(set_addr[7:0])
			'd0:state_data<=crc_error_sum_2[7:0];
			'd1:state_data<=crc_error_sum_2[15:8];
			'd2:state_data<=pkt_sum_2[7:0];
			'd3:state_data<=pkt_sum_2[15:8];
			'd4:state_data<=pkt_sum_2[23:16];
			'd5:state_data<=pkt_sum_2[31:24];
			'h40:	if ((sub_mode == 0) && (main_function == "L"))
					state_data <= "V";
				else
					state_data <= main_function;
			'h41:state_data<=sub_function;
			'h42:state_data<=main_solution;
			'h43:state_data<=sub_solution;
			'h44:state_data<=application_type;
			'h45:state_data<=main_version;
			'h46:state_data<=sub_version;
			'h47:state_data<=mini_version;
			'hFE:state_data<=8'hFE;
			'hFF:state_data<=8'hFF;
			default state_data<=rd_data;
		endcase

//**************************************************************
assign	tout = 0;
			
endmodule